Real-time operating environments enable computers to perform time-constrained functions. Examples of time-constrained functions include executing tasks at regular time intervals (e.g., automatically updating a user interface), running a program at a given time (e.g., reading input from a peripheral for a given period of time), or delaying the execution of a task for a given time period. Any of the latter functions may be triggered, for example, by a timer and/or a software event.
A real-time operating system typically comprises a kernel and a number of applications and drivers. The kernel is the part of the operating system that manages the execution of applications and the inputs and outputs through drivers. A task, in computer code terms, is a piece of code (e.g., computer application or a part thereof) designed to enable the computer to provide a given functionality.
Modern real-time operating systems are able to virtually simultaneously execute more than one task by switching from one task to another, an operation that requires sharing execution time in a scheduled manner (conventionally referred to as “time-slicing”). The kernel determines, at each time period, the next task to execute/resume. Thus, in existing real-time operating systems, each task must be designed to be able to execute, suspend execution, resume execution, and stop. For instance, a task may need to stop in order to wait for new input, or when it is preempted by another task.
The system utilizes a stack to be able to store the state of a task when stopping its execution, and re-establish its state when the execution resumes. Since modern programs typically use a stack to execute function calls, a task needs its own stack in order to run, stop and resume running. For example, in the case of switching from a task “A” to a task “B”, the system switches the execution context from task “A” to task “B” by saving the registers of task “A” to stack of “A”, then restoring previously-saved registers of task “B” from stack of “B”. In existing operating environments a task possesses an entry point that is unique, a mailbox (or message queue) for receiving messages, and a dispatcher for dispatching messages, each linked to the appropriate part of the program code within the task once it is invoked.
The purpose of a task-based architecture in real-time operating systems is the ability to handle multiple time-sensitive tasks, thus the need to switch between multiple tasks on the basis of each task's priority level. At each time slice (or following an interrupt), the real-time operating system uses the priority level to determine the next task to be executed. For instance, a low priority task can run the main algorithms, while a higher priority task can execute time sensitive code. The high priority task conventionally preempts the low priority task at almost any point in time.
Existing real-time operating systems present many limitations with regard to task management, however. For a software engineer, developing programs for a real-time operating system is a time-consuming and error prone endeavor. A programmer must manually assign priority levels and create messages for communications between different tasks. For example, if a function “F” runs within task “A”, it is impossible to call it from task “B” in existing systems. The way to call function “F” is by sending a message to task “B”, the message containing information regarding which function to call and including the parameters to pass to function “F”. In existing real-time operating systems architecture, the developer is compelled to manually assign functions to tasks and write messages to transmit between tasks, which increases development time and reduces the modularity of a program.
Therefore, there is a need for an improved architecture that allows a programmer to automatically implement program management tools in order to facilitate runtime task switching and management.